home *** CD-ROM | disk | FTP | other *** search
- /*
- * Stripped down tip clone -- Howard Chu, 10-10-90
- *
- * This is a very simple terminal program intended for use with MiNT
- * (and MGR...). I tried to model it on the BSD 4.3 version of tip,
- * but got impatient and thus omitted a number of features. Still,
- * this is useful enough and easy enough to use... You may copy and
- * distribute this program freely as long as you keep all files intact
- * (meaning this source file and the accompanying doc and executable
- * file). You are also welcome to modify the program to suit your own
- * needs, but leave this notice intact. I would also appreciate it
- * if you send me any improvements you may make.
- * hyc@math.lsa.umich.edu
- */
- #include <osbind.h>
- #include <xbios.h>
-
- #define Finstat(a) gemdos(0x105,a)
- #define Foutstat(a) gemdos(0x106,a)
- #define Fgetchar(a,b) gemdos(0x107,a,b)
- #define Fputchar(a,b,c) gemdos(0x108,a,b,c)
-
- /* The previous 4 defines don't actually get used. So it goes...
- they're up there because I thought about using them, and I haven't
- incorporated them into my MWC library yet. */
-
- #define Pgetpid() gemdos(0x10b)
- #define Pkill(a,b) gemdos(0x111,a,b)
-
- char iobuf[8192];
- struct iorec *rec, oldirec, oldorec;
-
- char shell[128], esc='~';
- int par=0; /* none, odd, even - 0, 1, 2 */
- int baud=1; /* see baud table 1=9600 */
- int echo=0;
- int flow=0; /* none, xon/xoff, rts/cts */
-
- int ucr, rsr, tsr, scr;
-
- char *bauds[]={"19200","9600","4800","3600","2400","2000","1800","1200",
- "600","300","200","150","134","110","75","50"};
-
- /* Set up a large I/O buffer for the RS232 port, and set initial
- speed, flow control, and parity. */
-
- void rs232init(){
- register long m68901reg;
-
- rec=Iorec(0);
-
- oldirec=*rec;
-
- rec->io_buff=iobuf;
- rec->io_bufsiz = 4096;
- rec->io_head = 0;
- rec->io_tail = 0;
- rec->io_low = 100;
- rec->io_high = 4000;
-
- rec++;
-
- oldorec=*rec;
- rec->io_buff=&iobuf[4096];
- rec->io_bufsiz = 4096;
- rec->io_head=0;
- rec->io_tail=0;
- rec->io_low=100;
- rec->io_high=4000;
-
- m68901reg=Rsconf(baud,0,-1,-1,-1,-1);
- scr=m68901reg&0xff;
- m68901reg>>=8;
- tsr=m68901reg&0xff;
- m68901reg>>=8;
- rsr=m68901reg&0xff;
- m68901reg>>=8;
- ucr=m68901reg&0xf8;
- Rsconf(-1,-1,ucr,-1,-1,-1); /* turn off parity */
- }
-
- int getbaud(rate)
- char *rate;
- {
- register int i;
-
- for (i=0;i<16;i++)
- if (!strcmp(rate,bauds[i]))
- break;
-
- if (i==16) {
- Cconws(rate);
- Cconws(": unknown baudrate value\r\n");
- i=(-1);
- }
- return(i);
- }
-
- main(argc,argv)
- int argc; char *argv[];
- {
- register int c;
- register int cr=0;
- register int cmd=0;
- char *buf, *getenv();
-
- void docommand();
-
- switch(argc){
- case 1:
- break;
- case 2:
- c=getbaud(argv[1]);
- if (c>=0)
- baud=c;
- break;
- default:
- Cconws("Use: tip [speed]\r\n");
- break;
- }
-
- rs232init();
-
- buf=getenv("SHELL");
- if (buf)
- strcpy(shell,buf);
-
- for(;;) {
- if (Bconstat(1)) {
- c = Bconin(1);
- Bconout(2,c);
- }
- if (Cconis()) {
- c = Crawcin();
- if (cmd) {
- cmd=0;
- docommand(c);
- cr=1;
- continue;
- } else if (cr && c == esc) {
- cmd = 1;
- cr = 0;
- continue;
- } else if (c == '\r')
- cr = 1;
- else cr = 0;
- if (Bcostat(1))
- Bconout(1,c);
- if (echo)
- Bconout(2,c);
- }
- }
-
- }
-
- void docommand(c)
- int c;
- {
- int args=0;
- void dosetvar(), dobreak();
- char *strchr();
-
- if (strchr("!#.?s",c)||(c==4)||(c==26))
- Cconout(esc);
-
- switch (c) {
- case '!':
- if (shell[0]) {
- Cconws("\r\n[sh]\r\n");
- Pexec(0,shell,&args,0L);
- } else {
- Cconws("No shell.\r\n");
- }
- break;
- #if 0 /* Not implemented. Too much hassle. */
- case '|':
- Cconws("Local command? ");
- Cconws("List command for remote system? ");
- case '$':
- /* Pipe local command to remote */
- case 'C':
- Cconws("Local command? ");
- #endif
- case '.':
- case 4:
- Cconws("\r\n[EOT]\r\n");
- *rec=oldorec; /* reset to old I/O rec stuff, then exit */
- rec--;
- *rec=oldirec;
- exit(0);
- case 26: /* Send a STOP to this process */
- {register int i = Pgetpid();
- Pkill(i,17);
- }
- break;
- case 's':
- dosetvar();
- break;
- case '#':
- dobreak();
- break;
- case '?':
- Cconws("\r\n ~! shell\r\n");
- Cconws(" ~. exit from tip\r\n");
- Cconws(" ~^D exit from tip\r\n");
- Cconws(" ~^Z suspend tip\r\n");
- Cconws(" ~s set variable\r\n");
- Cconws(" ~# send break\r\n");
- Cconws(" ~? get this summary\r\n");
- break;
- default:
- Bconout(1,c);
- break;
- }
- }
-
- void dobreak()
- {
- #define Fselect(a,b,c,d) gemdos(0x11d,a,b,c,d)
- tsr |= 0x08;
- Rsconf(-1,-1,-1,-1,tsr,-1);
- Fselect(300,0L,0L,0L); /* sleep 300 milliseconds */
- tsr &=0xf7;
- Rsconf(-1,-1,-1,-1,tsr,-1);
- }
-
- char *vars[]={"all","baudrate","flowcontrol","localecho","parity","escape","shell"};
- char *flows[]={"none","xon/xoff","rts/cts"};
- char *pars[]={"none","odd","even"};
-
- void dosetvar()
- {
- register int i, j;
- char *strpbrk();
- unsigned char buf[130];
- register char *ptr;
-
- Cconws("[set] ");
- buf[0]=128;
- Cconrs(buf);
- Cconout('\n');
-
- i=buf[1];
- if (i==0)
- return;
-
- buf[i+2]='\0';
-
- ptr=strpbrk(&buf[2]," = ");
- if (ptr)
- i=ptr-&buf[2];
- else
- i=buf[1];
-
- for (j=0;j<7;j++)
- if(!strncmp(&buf[2],vars[j],i))
- break;
-
- if (j==7) {
- Cconws(&buf[2]);
- Cconws(": unknown variable\r\n");
- return;
- }
-
- if (j&&!ptr) {
- Cconws("\r\nno value supplied\r\n");
- return;
- }
-
- ptr++;
- switch(j) {
- case 0:
- Cconws("baudrate=");
- Cconws(bauds[baud]);
- Cconws("\r\nflowcontrol=");
- Cconws(flows[flow]);
- Cconws("\r\nlocalecho=");
- ptr=echo ? "on":"off";
- Cconws(ptr);
- Cconws("\r\nparity=");
- Cconws(pars[par]);
- Cconws("\r\nescape=");
- Cconout(esc);
- Cconws("\r\nshell=");
- Cconws(shell);
- Cconws("\r\n");
- break;
- case 1:
- i=getbaud(ptr);
- if (i>=0) {
- baud=i;
- Rsconf(i,-1,-1,-1,-1,-1);
- }
- break;
- case 2:
- j=buf[1]-i-1;
- for (i=0;i<4;i++)
- if (!strncmp(ptr,flows[i],j))
- break;
- if (i==4) {
- Cconws(ptr);
- Cconws(": unknown flowcontrol value\r\n");
- return;
- }
- flow=i;
- Rsconf(-1,i,-1,-1,-1,-1);
- break;
- case 3:
- echo=strcmp(ptr,"on") ? 0 : 1;
- break;
-
- case 4:
- j=buf[1]-i-1;
- for (i=0;i<3;i++)
- if (!strncmp(ptr,pars[i],j))
- break;
- if (i==3) {
- Cconws(ptr);
- Cconws(": unknown parity value\r\n");
- return;
- }
- par=i;
- ucr &=0x98;
- if (i) {
- ucr |= i|0x24; /* set 7 bits, parity on */
- }
- Rsconf(-1,-1,ucr,-1,-1,-1);
- break;
- case 5:
- esc=*ptr;
- break;
- case 6:
- strcpy(shell,ptr);
- break;
- }
- }
-